<?php
include $_SERVER['DOCUMENT_ROOT'] . '/paths.php';
include $COMPONENT_SITE;
include $COMPONENT_SIDEBAR;
  
$jumbo = '
<h1 class="nocount">OpenGL Beginner Course</h1>
<h2 class="nocount">Tutorial 1 - Creating a Window</h2>
';

$sidebar_array = array();
$sidebar_array[0]['anchor'] = '#preview';
$sidebar_array[0]['text'] = 'Preview';
$sidebar_array[1]['anchor'] = '#libraries';
$sidebar_array[1]['text'] = 'Libraries';
$sidebar_array[2]['anchor'] = '#code';
$sidebar_array[2]['text'] = 'Code';
$sidebar_array[2]['data-target'] = 'code-submenu';
$sidebar_array[2]['data-target-elems'][0]['anchor'] = '#glfw-error-callback';
$sidebar_array[2]['data-target-elems'][0]['text'] = 'GLFW Error Callback';
$sidebar_array[2]['data-target-elems'][1]['anchor'] = '#initialize-context';
$sidebar_array[2]['data-target-elems'][1]['text'] = 'Initialize the OpenGL Context';
$sidebar_array[2]['data-target-elems'][2]['anchor'] = '#creating-window';
$sidebar_array[2]['data-target-elems'][2]['text'] = 'Creating a Window';

$sidebar = getSideBar($sidebar_array);

  
$content = '
<span class="anchor" id="preview"></span>
<h1>Preview</h1>
<p>At the end of this tutorial you will be able to create a window like the
  following.</p>
<img src="' . $PATH_IMAGES . '/OpenGLBeginner1Result.png" class="img-rounded">

<span class="anchor" id="libraries"></span>
<h1>Libraries</h1>
<p>For window and input related things I always use <a href="http://www.glfw.org/">
  GLFW</a>. All it does is defining an OpenGL context and handling input. So
  it has a very well defined scope.</p>
<p>To install it have to build it yourself:</p>
<ol>
  <li>Download a stable version from their <a href="http://www.glfw.org/">
  Website</a>.</li>
  <li>Unzip it.</li>
  <li>Open a Terminal and go into the extracted folder.</li>
  <li><p>Type into the Terminal:</p>
<pre class="prettyprint linenums">
mkdir build && cd build && cmake -DBUILD_SHARED_LIBS=ON ..
make
make install
</pre>
</ol>
<p>Now you should have the glfw binaries in the correct location on your system.</p>
  
<span class="anchor" id="code"></span>
<h1>Code</h1>
<p>First we have to include the necessary headers to use GLFW.</p>
<pre class="prettyprint linenums">
#include <GLFW/glfw3.h>
</pre>
<p>Now after that is done, we can move on to our main function</p>
<pre class="prettyprint linenums">
int main(int argc, char** argv)
{
  return EXIT_SUCCESS;
}
</pre>
  
<span class="anchor" id="glfw-error-callback"></span>
<h2>GLFW Error Callback</h2>
<p>GLFW allows it to define an error callback. This is a function, that is
  called, whenever an error happens with anything related to GLFW. So let\'s
  use this opportunity.</p>
<pre class="prettyprint linenums">
void glfwErrorCallback(int error, const char* description)
{
  cerr << "GLFW Error: " << description << endl;
}
</pre>
<p>So in case of an error we just report it using <code>std::cerr</code></p>
<p>Now we have to tell GLFW about our callback. To do so we handle them the
  function pointer.</p>
<pre class="prettyprint linenums">
int main(int argc, char** argv)
{
  glfwSetErrorCallback(glfwErrorCallback);
  return EXIT_SUCCESS;
}
</pre>
<p>Now, whenever an error happens, we\'d get a message like the following.</p>
<pre class="prettyprint linenums">
GLFW Error: Context profiles only exist for OpenGL version 3.2 and above
</pre>

<span class="anchor" id="initialize-context"></span>
<h2>Initialize the OpenGL Context</h2>
<p>Now that we have set an error callback to inform us when something wents
  wrong, we can go on and initialize GLFW. This must be done before any other
  GLFW function is called. Otherwise you will get an error message indicating
  that you have to do it. To init GLFW just add the following to your main
  function:</p>
<pre class="prettyprint linenums">
  if (!glfwInit())
    return EXIT_FAILURE;
</pre>
<p>Next thing to do is to set some hints for the context creation. Of course
  you could go with the defaults, but I strongly recommend to set them by
  yourself. This is the only way to be sure that they are really what you
  want them to be.</p>
<p>First we are going to define the desired OpenGL version.</p>
<pre class="prettyprint linenums">
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
</pre>
<p>This tells GLFW that it should create a context of version 4.3. However 
  in some cases (like on OSX) you will have to use a forward compatible core
  profile. Otherwise the context creation will fail. The additional hints
  look like the following.</p>
<pre class="prettyprint linenums">
  glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, true);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
</pre>
<p>It\'s also a good idea to set the sizes for the colour channels and
  things like depth/stencil buffers.</p>
<pre class="prettyprint linenums">
  glfwWindowHint(GLFW_RED_BITS, 8);
  glfwWindowHint(GLFW_GREEN_BITS, 8);
  glfwWindowHint(GLFW_BLUE_BITS, 8);
  glfwWindowHint(GLFW_ALPHA_BITS, 8);
  glfwWindowHint(GLFW_DEPTH_BITS, 24);
  glfwWindowHint(GLFW_STENCIL_BITS, 0); 
</pre>
<p>I will talk more about the different buffers in the next tutorials.</p>

<span class="anchor" id="creating-window"></span>
<h2>Creating a Window</h2>
<p>After we\'ve defined the hints for the context, the actual creation is
  pretty simple:</p>
<pre class="prettyprint linenums">
  GLFWwindow* window = glfwCreateWindow(640, 480, "Tutorial 1 - Creating a Window", NULL, NULL);
  if (!window)
  {
    glfwTerminate();
    return EXIT_FAILURE;
  }
</pre>
<p>The first 2 parameters of the <code>glfwCreateWindow</code> function define
  the width and height of the created window and the 3rd parameter is the title.
  The 4th parameter is important if you want to run in fullscreen mode.
  For further information about retrieving video modes please consult the
  <a href="http://www.glfw.org/docs/latest/monitor.html">Multi-Monitor Guide</a>
  on the GLFW website.</p>
<p>If the creation fails we call <code>glfwTerminate</code>. This function cleans
  up everything relating to GLFW. If any windows are open, this function would
  close them.</p>
<p>Now we just have to make the created context to the current context so that we
  can render and use it for GL operations. To do this we just add this.</p>
<pre class="prettyprint linenums">
  glfwMakeContextCurrent(window);
</pre>
<p>Now we have created a window with a valid OpenGL context, based on our hints,
  and set it active. Let\'s move on to the Main-Loop.</p>
';

echo '<!DOCTYPE html><html>';

echo getDefaultHeader("Graphiclicious - OpenGL Beginner Course");

echo getDefaultBody(1, $jumbo, $sidebar, $content);

echo '</html>';

echo getDefaultAffixScript();
?>
